// main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>

// 检查是否为有效的十六进制字符
int is_valid_hex_char(char c) {
    return (c >= '0' && c <= '9') || 
           (c >= 'a' && c <= 'f') || 
           (c >= 'A' && c <= 'F');
}

// 验证十六进制字符串格式
int validate_hex_string(const char *hex_str) {
    if (!hex_str || strlen(hex_str) == 0) {
        return 0;  // 空字符串
    }
    
    // 跳过可能的"0x"或"0X"前缀
    const char *ptr = hex_str;
    if (strlen(hex_str) > 2 && hex_str[0] == '0' && (hex_str[1] == 'x' || hex_str[1] == 'X')) {
        ptr += 2;
    }
    
    // 检查是否为空字符串
    if (strlen(ptr) == 0) {
        return 0;
    }
    
    // 限制最大长度 (防止溢出)
    if (strlen(ptr) > 8) {  // 32位整数最多8个十六进制字符
        return 0;
    }
    
    // 验证每个字符
    while (*ptr) {
        if (!is_valid_hex_char(*ptr)) {
            return 0;
        }
        ptr++;
    }
    
    return 1;
}

// 转换字符到十六进制值
int hex_char_to_value(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
    return -1;  // 无效字符
}

// 手动解析十六进制字符串为整数，避免sscanf潜在问题
int parse_hex_manually(const char *hex_str) {
    const char *ptr = hex_str;
    int result = 0;
    int prev_result = 0;
    
    // 跳过可能的"0x"或"0X"前缀
    if (strlen(hex_str) > 2 && hex_str[0] == '0' && (hex_str[1] == 'x' || hex_str[1] == 'X')) {
        ptr += 2;
    }
    
    // 逐位解析
    while (*ptr) {
        int digit_value = hex_char_to_value(*ptr);
        
        // 检查溢出
        if ((result > INT_MAX / 16) || 
            (result == INT_MAX / 16 && digit_value > INT_MAX % 16)) {
            fprintf(stderr, "错误：十六进制值过大，发生溢出\n");
            exit(EXIT_FAILURE);
        }
        
        // 更新结果
        prev_result = result;
        result = result * 16 + digit_value;
        
        // 额外的溢出检查
        if (result < prev_result) {
            fprintf(stderr, "错误：十六进制值过大，发生溢出\n");
            exit(EXIT_FAILURE);
        }
        
        ptr++;
    }
    
    return result;
}

// 解析十六进制字符串为整数
int parse_hex(const char *hex_str) {
    // 验证输入格式
    if (!validate_hex_string(hex_str)) {
        fprintf(stderr, "错误：无效的十六进制输入 '%s'\n", hex_str);
        fprintf(stderr, "十六进制数应由数字0-9和字母A-F组成，可以选择添加0x前缀。\n");
        fprintf(stderr, "最多支持8个十六进制字符（不含前缀），对应32位整数范围。\n");
        exit(EXIT_FAILURE);
    }
    
    // 首先尝试我们自己的解析方法
    return parse_hex_manually(hex_str);
}

// 检测算术运算是否会导致溢出
int detect_overflow(int a, int b, char op) {
    switch (op) {
        case '+':
            // 加法溢出检测
            if ((b > 0 && a > INT_MAX - b) || (b < 0 && a < INT_MIN - b))
                return 1;
            break;
        case '-':
            // 减法溢出检测
            if ((b < 0 && a > INT_MAX + b) || (b > 0 && a < INT_MIN + b))
                return 1;
            break;
        case '*':
            // 乘法溢出检测
            if (a > 0 && b > 0 && a > INT_MAX / b)
                return 1;
            if (a > 0 && b < 0 && b < INT_MIN / a)
                return 1;
            if (a < 0 && b > 0 && a < INT_MIN / b)
                return 1;
            if (a < 0 && b < 0 && a < INT_MAX / b)
                return 1;
            break;
        case '/':
            // 除法特殊情况检测
            if (b == 0 || (a == INT_MIN && b == -1))
                return 1;
            break;
    }
    return 0;
}

// 执行算术运算
int calculate(int a, int b, char op) {
    // 检测可能的溢出
    if (detect_overflow(a, b, op)) {
        if (op == '/' && b == 0) {
            fprintf(stderr, "错误：除数不能为零\n");
        } else {
            fprintf(stderr, "错误：运算会导致整数溢出\n");
        }
        exit(EXIT_FAILURE);
    }
    
    switch (op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return a / b;
        default:
            fprintf(stderr, "错误：无效的运算符 '%c'\n", op);
            fprintf(stderr, "支持的运算符: +, -, *, /\n");
            exit(EXIT_FAILURE);
    }
}

// 格式化十六进制输出
void print_hex_result(int value) {
    // 检查是否为负数
    if (value < 0) {
        printf("十六进制结果: -0x%X\n", -value);
    } else {
        printf("十六进制结果: 0x%X\n", value);
    }
}

void display_help() {
    printf("\n十六进制计算器使用说明:\n");
    printf("--------------------------\n");
    printf("格式: [十六进制数] [运算符] [十六进制数]\n");
    printf("示例: 0xA + 0x5\n");
    printf("      FF - 5\n"); 
    printf("\n支持的运算符:\n");
    printf("  + : 加法\n");
    printf("  - : 减法\n");
    printf("  * : 乘法\n");
    printf("  / : 除法\n");
    printf("\n输入格式说明:\n");
    printf("  - 十六进制数可以带0x/0X前缀或不带\n");
    printf("  - 最大支持8位十六进制数 (32位整数范围内)\n");
    printf("  - 不区分大小写 (0xff 等同于 0xFF)\n");
    printf("\n特殊命令:\n");
    printf("  help 或 ? : 显示此帮助信息\n");
    printf("  q 或 exit : 退出程序\n");
    printf("--------------------------\n\n");
}

void clear_input_buffer() {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

int main() {
    char input[100];
    char hex1[50], hex2[50], op;

    display_help();

    while (1) {
        printf("请输入 (格式: 数值1 运算符 数值2): ");
        
        if (!fgets(input, sizeof(input), stdin)) {
            fprintf(stderr, "错误：读取输入失败\n");
            return EXIT_FAILURE;
        }
        
        // 去除末尾的换行符
        input[strcspn(input, "\n")] = 0;
        
        // 检查是否要退出
        if (strcmp(input, "q") == 0 || strcmp(input, "exit") == 0) {
            printf("程序退出\n");
            break;
        }
        
        // 检查是否需要显示帮助
        if (strcmp(input, "help") == 0 || strcmp(input, "?") == 0) {
            display_help();
            continue;
        }
        
        // 解析输入
        if (sscanf(input, "%49s %c %49s", hex1, &op, hex2) != 3) {
            fprintf(stderr, "错误：输入格式无效，请按照 '数值1 运算符 数值2' 的格式输入\n");
            fprintf(stderr, "输入 'help' 或 '?' 获取帮助\n\n");
            continue;
        }

        // 尝试解析和计算
        int num1, num2, result;
        int error = 0;
        
        // 解析第一个数值
        if (!error) {
            if (!validate_hex_string(hex1)) {
                fprintf(stderr, "错误：'%s' 不是有效的十六进制数\n", hex1);
                fprintf(stderr, "十六进制数应由数字0-9和字母A-F组成，可以选择添加0x前缀。\n\n");
                error = 1;
            } else {
                num1 = parse_hex(hex1);
            }
        }
        
        // 解析第二个数值
        if (!error) {
            if (!validate_hex_string(hex2)) {
                fprintf(stderr, "错误：'%s' 不是有效的十六进制数\n", hex2);
                fprintf(stderr, "十六进制数应由数字0-9和字母A-F组成，可以选择添加0x前缀。\n\n");
                error = 1;
            } else {
                num2 = parse_hex(hex2);
            }
        }
        
        // 执行计算
        if (!error) {
            result = calculate(num1, num2, op);
            
            // 显示结果
            printf("\n计算: ");
            // 如果原输入带前缀则显示前缀，否则不显示
            if (strstr(hex1, "0x") == hex1 || strstr(hex1, "0X") == hex1) {
                printf("0x%X ", num1);
            } else {
                printf("%X ", num1);
            }
            
            printf("%c ", op);
            
            if (strstr(hex2, "0x") == hex2 || strstr(hex2, "0X") == hex2) {
                printf("0x%X\n", num2);
            } else {
                printf("%X\n", num2);
            }
            
            printf("十进制结果: %d\n", result);
            print_hex_result(result);
            printf("\n");
        }
    }

    return EXIT_SUCCESS;
}